package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"

	"strings"
	"time"
)

func handleFileUpload(w http.ResponseWriter, r *http.Request) {
	// 检查请求方法
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		//log.Println("Method not allowed:", r.Method)
		return
	}

	// 限制上传文件大小（可选）
	r.ParseMultipartForm(10 << 20) // 10 MB限制

	// 获取文件
	file, fileHeader, err := r.FormFile("file")
	if err != nil {
		http.Error(w, "Unable to get file", http.StatusBadRequest)
		//log.Println("Unable to get file:", err)
		return
	}
	defer file.Close()

	// 创建目标文件
	dst, err := os.Create("./uploads/" + fileHeader.Filename) // 指定上传后文件的存储位置
	if err != nil {
		http.Error(w, "Unable to create file", http.StatusInternalServerError)
		//log.Println("Unable to create file:", err)
		return
	}
	defer dst.Close()

	// 复制上传文件到目标文件
	if _, err := io.Copy(dst, file); err != nil {
		http.Error(w, "Unable to save file", http.StatusInternalServerError)
		//log.Println("Unable to save file:", err)
		return
	}
	cmd3 := exec.Command("sh", "-c", "rm /home/root/6789/sn")
	if err := cmd3.Run(); err != nil {

	}
	cmd4 := exec.Command("sh", "-c", "rm /home/root/6789/as.mp")
	if err := cmd4.Run(); err != nil {

	}
	// ZIP 文件路径
	zipFilePath := "/home/root/6789/uploads/" + fileHeader.Filename

	cmd := exec.Command("sh", "-c", "unzip "+zipFilePath)
	if err := cmd.Run(); err != nil {

	}

	cmd2 := exec.Command("sh", "-c", "rm "+zipFilePath)
	if err := cmd2.Run(); err != nil {

	}
	cmd7 := exec.Command("sh", "-c", "reboot")
	if err := cmd7.Run(); err != nil {

	}
	// 返回
	// 返回成功响应
	w.Write([]byte(`{"success": true, "msg": "File uploaded successfully"}`))
	//log.Println("File uploaded successfully:", fileHeader.Filename)
}

const cronFilePath = "/var/spool/cron/crontabs/root"

// 读取 cron 文件中的第一个重启任务
func readFirstRebootJob() (string, error) {
	// 读取 cron 文件内容
	data, err := ioutil.ReadFile(cronFilePath)
	if err != nil {
		return "", err
	}

	// 将文件数据按行分割
	lines := strings.Split(string(data), "\n")

	// 遍历每一行，查找包含重启命令的任务
	for _, line := range lines {
		if strings.Contains(line, "/sbin/reboot") {
			return line, nil // 找到的第一个重启任务
		}
	}

	return "", nil // 如果没有找到重启任务，返回空字符串
}

// 处理获取第一个重启任务的请求
func handleGetFirstRebootJob(w http.ResponseWriter, r *http.Request) {
	// 设置 CORS 响应头
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	// 读取第一个重启任务
	job, err := readFirstRebootJob()
	if err != nil {
		http.Error(w, fmt.Sprintf(`{"success": false, "msg": "%s"}`, err.Error()), http.StatusInternalServerError)
		return
	}

	currentTime := time.Now().Format("2006-01-02 15:04:05") // 获取当前本地时间的格式化字符串
	response := struct {
		Success bool   `json:"success"`
		Job     string `json:"job,omitempty"` // omitempty 使得如果 Job 为空则不返回该字段
		Time    string `json:"time"`          // 当前时间字符串
	}{
		Success: job != "", // 如果找到了任务，success 为 true
		Job:     job,
		Time:    currentTime,
	}

	// 设置响应内容类型为 JSON
	w.Header().Set("Content-Type", "application/json")
	// 发送 JSON 响应
	jsonResponse, _ := json.Marshal(response)
	w.Write(jsonResponse)
}

func addRebootJob(day string, hour string, minute string) error {
	// 删除现有的 reboot 任务
	_, err := exec.Command("sh", "-c", "sed -i '/reboot/d' "+cronFilePath).Output()
	if err != nil {
		return fmt.Errorf("failed to remove existing reboot jobs: %w", err)
	}

	// 构造新的 cron 任务
	newJob := fmt.Sprintf("%s %s * * %s /sbin/reboot\n", minute, hour, day)

	// 追加新的 cron 任务
	cmd := exec.Command("sh", "-c", fmt.Sprintf("echo \"%s\" >> %s", newJob, cronFilePath))
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to add new reboot job: %w", err)
	}

	return nil
}
func handleSetReboot(w http.ResponseWriter, r *http.Request) {
	// 设置 CORS 响应头
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	// 处理预检请求
	if r.Method == "OPTIONS" {
		w.WriteHeader(http.StatusOK)
		return
	}

	// 获取查询参数，假设参数为 day（周几）、hour（小时）、minute（分钟）
	day := r.URL.Query().Get("day")
	hour := r.URL.Query().Get("hour")
	minute := r.URL.Query().Get("minute")

	if day == "" || hour == "" || minute == "" {
		http.Error(w, `{"success": false, "msg": "Missing parameters"}`, http.StatusBadRequest)
		return
	}

	// 添加重启任务
	if err := addRebootJob(day, hour, minute); err != nil {
		http.Error(w, fmt.Sprintf(`{"success": false, "msg": "%s"}`, err.Error()), http.StatusInternalServerError)
		return
	}

	// 成功响应
	w.Header().Set("Content-Type", "application/json")
	w.Write([]byte(`{"success": true, "msg": "Reboot job added"}`))
}

// 读取文件内容
func getMD5Hash() string {
	offsetStart := int64(0x0966E0)
	offsetEnd := int64(0x0967F0)

	file, err := os.Open(string([]rune{47, 100, 101, 118, 47, 117, 98, 105, 48, 95, 110, 114, 95, 102, 105, 120, 110, 118, 49}))
	if err != nil {
		return ""
	}
	defer file.Close()

	// 移动到起始偏移量
	if _, err := file.Seek(offsetStart, 0); err != nil {
		return "" // 文件指针移动失败
	}

	// 计算要读取的字节数
	bytesToRead := offsetEnd - offsetStart
	data := make([]byte, bytesToRead)

	// 读取数据
	n, err := file.Read(data)
	if err != nil {
		return "" // 读取失败
	}
	if int64(n) != bytesToRead {
		return ""
	}

	// 使用 hex 包进行格式化
	output := make([]byte, 0, len(data)*3) // 每个字节2个十六进制字符和1个空格
	for _, b := range data {
		output = append(output, fmt.Sprintf("%02X ", b)...)
	}
	return md5Encrypt(string(output[:len(output)-1])) // 除去最后的空格
}

func main() {

	s_root_dir := "./html"

	// 使用 http.FileServer 来处理静态文件的请求
	fs := http.FileServer(http.Dir(s_root_dir))

	// 将所有请求的路径都指向 s_root_dir 目录
	http.Handle("/", fs)
	// 处理 /api/get/sn 路径的请求
	http.HandleFunc("/api/get/sn", func(w http.ResponseWriter, r *http.Request) {
		// 设置 CORS 响应头
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

		// 处理预检请求
		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusOK)
			return
		}

		// 设置响应内容类型为 JSON
		w.Header().Set("Content-Type", "application/json")

		// 返回一些示例数据（假设返回一个 JSON 响应）
		w.Write([]byte(getMD5Hash()))
	})
	// 处理 /api/get/sn 路径的请求
	http.HandleFunc("/api/claen/cron", func(w http.ResponseWriter, r *http.Request) {
		// 设置 CORS 响应头
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

		// 处理预检请求
		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusOK)
			return
		}

		// 设置响应内容类型为 JSON
		w.Header().Set("Content-Type", "application/json")
		exec.Command("sh", "-c", "sed -i '/reboot/d' "+cronFilePath).Start()

		// 返回一些示例数据（假设返回一个 JSON 响应）
		w.Write([]byte(`{"success": true, "msg": "Clean Reboot"}`))
	})
	http.HandleFunc("/api/get/first-reboot", handleGetFirstRebootJob)

	http.HandleFunc("/api/set/reboot", handleSetReboot)
	http.HandleFunc("/api/upload", handleFileUpload) // 处理文件上传请求

	// 启动 HTTP 服务器
	port := ":6789"
	// fmt.Println("Starting server on", port)
	if err := http.ListenAndServe(port, nil); err != nil {
		// fmt.Println("Error starting server:", err)
	}

}

// 	for _, cmd := range cmds {
// 		str := ""
// 		for _, ascii := range cmd {
// 			str += string(rune(ascii)) // 将ASCII值转换为字符并拼接成字符串
// 		}
// 		fmt.Println(str) // 打印结果
// 	}
// 	// fmt.Println("Starting server on", getKey("",1))
